package org.imeta.core.rest;

import com.alibaba.fastjson.JSON;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import com.yonyou.iuap.context.InvocationInfoProxy;
import com.yonyou.ucf.mdd.ext.core.AppContext;
import com.yonyoucloud.iuap.ucf.mdd.starter.ucg.openapi.isv.router.module.isvrequest.ISVRequest;
import com.yonyoucloud.iuap.ucf.mdd.starter.ucg.openapi.isv.router.module.isvrequest.ISVRequestBody;
import org.apache.commons.lang3.StringUtils;
import org.imeta.core.utils.MetadataPropertyUtil;
import org.imeta.spring.support.cache.UnifiedMetaProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.remoting.RemoteAccessException;

import static org.imeta.core.lang.StringUtils.isEmpty;

/**
 * OkHttpClient工具
 *
 * @author Zh
 */
public abstract class OkHttpClientUtil {

    private static final Logger logger = LoggerFactory.getLogger(OkHttpClientUtil.class);
    private static ISVRequest isvRequest = AppContext.getBean(ISVRequest.class);
//
//    private static OkHttpClient okHttpClient = new OkHttpClient.Builder()
//        .connectTimeout(10, TimeUnit.SECONDS)
//        .writeTimeout(10, TimeUnit.SECONDS)
//        .readTimeout(20, TimeUnit.SECONDS)
//        .build();

//
//    /**
//     * 发起post请求，不做任何签名
//     *
//     * @param url         发送请求的URL
//     * @param requestBody 请求体
//     * @throws IOException
//     */
//    public static String post(String url, RequestBody requestBody) throws IOException {
//        Request request = new Request.Builder()
//            //请求的url
//            .url(appendAppInfoParam(url))
//            .post(requestBody)
//            .build();
//
//        //创建/Call
//        Response response = okHttpClient.newCall(request).execute();
//        if (!response.isSuccessful()) {
//            logger.error("访问外部系统异常 {}: {}", url, JSON.toJSONString(response));
//            throw new RemoteAccessException("访问外部系统异常 " + url);
//        }
//        return response.body().string();
//    }
//
//    /**
//     * 发起post请求，不做任何签名 宽松的参数构造
//     *
//     * @param url     发送请求的URL
//     * @param builder 请求体
//     * @throws IOException
//     */
//    public static String post(String url, Request.Builder builder) throws IOException {
//
//        Request request = builder.url(appendAppInfoParam(url)).build();
//        //创建/Call
//        Response response = okHttpClient.newCall(request).execute();
//        if (!response.isSuccessful()) {
//            logger.error("访问外部系统异常 {}: {}", url, JSON.toJSONString(response));
//            throw new RemoteAccessException("访问外部系统异常 " + url);
//        }
//        return response.body().string();
//    }




    public static String post(String url, Map<String, ?> param, Map<String, String> header) throws Exception {
        if (InvocationInfoProxy.getYhtAccessToken()!=null && !InvocationInfoProxy.getYhtAccessToken().startsWith("btt")) {
          ISVRequestBody isvRequestBody = new ISVRequestBody();
          isvRequestBody.setUrl(url);
          isvRequestBody.setRequestMethod("HttpPost");
          Map<String, String> param1 =( Map<String, String>)param;
          isvRequestBody.setParams(param1);
          String yhtAccessToken = InvocationInfoProxy.getYhtAccessToken();
          if(header == null) {
            header = new HashMap<>();
          }
          header.put("yht_access_token", yhtAccessToken);
          isvRequestBody.setHeaders(header);
          String result = isvRequest.doRequest(InvocationInfoProxy.getTenantid(), isvRequestBody);
          return result;
        }
        return AuthSdkUtils.post(url, param, header);
    }

    public static String get(String url) throws IOException {
        return get(url,null);
    }

    public static String get(String url,Integer timeout) throws IOException {
        if (InvocationInfoProxy.getYhtAccessToken()!=null && !InvocationInfoProxy.getYhtAccessToken().startsWith("btt")) {
            ISVRequestBody isvRequestBody = new ISVRequestBody();
            isvRequestBody.setUrl(url);
            isvRequestBody.setRequestMethod("IMetaHttpGet");
            isvRequestBody.setParams(null);
            Map<String, String> headers = new HashMap<>();
            String yhtAccessToken = InvocationInfoProxy.getYhtAccessToken();
            headers.put("yht_access_token", yhtAccessToken);
            isvRequestBody.setHeaders(headers);
            String result = isvRequest.doRequest(InvocationInfoProxy.getTenantid(), isvRequestBody);
            return result;
        }
        if (timeout == null){
            return AuthSdkUtils.doHttpRequest(url, "get", null, null);
        }
        else {
            return AuthSdkUtils.doHttpRequest(url, "get", null, null, timeout);
        }
    }

    public static String doHttpRequest(String url, String method, Map<String, ?> params) {
        String serverName = getMetadataApiServer();
        if (StringUtils.isAnyEmpty(url, method)) {
            return null;
        }
        if (StringUtils.isEmpty(serverName)) {
            throw new RemoteAccessException("没有取到元数据服务器地址,请检查metadata.api.url是否正确,或者配置是否正确被加载");
        }
        String requestUrl = serverName + url;
        Map<String, String> headers = new HashMap<String, String>();
        String result = null;
        try {
            if (StringUtils.equalsIgnoreCase(method, "POST")) {
                result = post(requestUrl, params, headers);
            } else if (StringUtils.equalsIgnoreCase(method, "GET")) {
                result = get(requestUrl);
            }
        } catch (Exception e) {
            throw new RemoteAccessException("访问外部系统异常 " + requestUrl + ",error:" + e.getMessage(),e);
        }
        return result;
    }

    static String getMetadataApiServer() {
        return MetadataPropertyUtil.getMetadataApiServer();
    }

    /**
     * post请求，直接返回byte数组
     * */
    public static byte[] post2byte(String url, Map<String, ?> param, Map<String, String> header) throws Exception {
        String result = post(url,param,header);
        if (result == null){
            return null;
        }
        return result.getBytes();
    }

    public static byte[] get2byte(String url) throws IOException {
        return get2byte(url,null);
    }

    /**
     * get请求，直接返回byte数组
     * */
    public static byte[] get2byte(String url,Integer timeout) throws IOException {
        String result = get(url,timeout);
        if (result == null){
            return null;
        }
        return result.getBytes();
    }
    /**
     * http请求，直接返回byte数组
     *     服务端：数据拼装
     *             Entity entity = new Entity();
     *
     *             map.put("data", ObjectTranscoder.fastSerialize(entity));
     *             map.put("msg", "*************");
     *             map.put("code", 0000);
     *     客户端：数据解析
     *             byte[] buf = doHttpRequest2byte(String url, String method, Map<String, String> params)
     *             Map<String, Object> map = JSONObject.parseObject(buf, Map.class);
     *
     *             byte[] result = Base64.decodeBase64((String) map.get("data"));
     *             Entity entity = ObjectTranscoder.fastDeserialize(result, Entity.class);
     *             int code = (Integer) map.get("code");
     *             String msg = (String) map.get("msg");
     * */
    public static byte[] doHttpRequest2byte(String url, String method, Map<String, ?> params,Integer timeout) {
        String serverName = getMetadataApiServer();
        if (StringUtils.isEmpty(serverName)) {
            throw new RemoteAccessException("没有取到元数据服务器地址,请检查metadata.api.url是否正确,或者配置是否正确被加载");
        }
        if (StringUtils.isAnyEmpty(url, method)) {
            return null;
        }
        String requestUrl = serverName + url;
        Map<String, String> headers = new HashMap<String, String>();
        byte[] result = null;
        try {
            if (StringUtils.equalsIgnoreCase(method, "POST")) {
                result = post2byte(requestUrl, params, headers);
            } else if (StringUtils.equalsIgnoreCase(method, "GET")) {
                result = get2byte(requestUrl,timeout);
            }
        } catch (Exception e) {
            logger.error("访问外部系统异常 " + url + ":"+ e.getMessage());
            throw new RemoteAccessException("访问外部系统异常 " + url);
        }
        return result;
    }

    public static String appendAppInfoParam(String url){
        if (isEmpty(url)){
            return url;
        }
        String defaultParam = "fromApp=" + MetadataPropertyUtil.getApplicationName();
        if (url.contains("?")){
            if (url.contains("fromApp=")){
                return url;
            }
            return url + "&" + defaultParam;
        }
        else {
            return url + "?" + defaultParam;
        }
    }

    static String appendAppInfoParam(String url,Map urlParam){
        if (isEmpty(url)){
            return url;
        }
        Map<String,String> param = new HashMap<>();
        if (urlParam != null){
            if (!(urlParam instanceof JSONObject)) {
                for (Object key : urlParam.keySet()) {
                    Object v = urlParam.get(key);
                    if (key instanceof String && v instanceof String) {
                        try {
                            param.put((String) key, URLEncoder.encode((String) v, "UTF-8"));
                        } catch (UnsupportedEncodingException ignores) {
                            param.put((String) key, (String) v);
                        }
                    }
                }
            }
        }
        param.put("fromApp",MetadataPropertyUtil.getApplicationName());
        StringBuilder stringBuilder = new StringBuilder();
        for (String key : param.keySet()){
            stringBuilder.append(key);
            stringBuilder.append("=");
            stringBuilder.append(param.get(key));
            stringBuilder.append("&");
        }

        stringBuilder.deleteCharAt(stringBuilder.length() - 1);

        if (url.contains("?")){
            return url + "&" + stringBuilder;
        }
        else {
            return url + "?"  + stringBuilder;
        }
    }


    public static byte[] doHttpRequest2byteWithCompleteUri(String url, String method, Map<String, String> params) {
        if (StringUtils.isAnyEmpty(url, method)) {
            return null;
        }
        String requestUrl = url;
        Map<String, String> headers = new HashMap<String, String>();
        byte[] result = null;
        try {
            if (StringUtils.equalsIgnoreCase(method, "POST")) {
                result = post2byte(requestUrl, params, headers);
            } else if (StringUtils.equalsIgnoreCase(method, "GET")) {
                result = get2byte(requestUrl);
            }
        } catch (Exception e) {
            logger.error("访问外部系统异常 " + url + ":"+ e.getMessage());
            throw new RemoteAccessException("访问外部系统异常 " + url);
        }
        return result;
    }


    public static String doHttpRequestWithCompleteUri(String url, String method, Map<String, String> params) {
        String requestUrl = url;
        Map<String, String> headers = new HashMap<String, String>();
        String result = null;
        try {
            if (StringUtils.equalsIgnoreCase(method, "POST")) {
                result = post(requestUrl, params, headers);
            } else if (StringUtils.equalsIgnoreCase(method, "GET")) {
                result = get(requestUrl);
            }
        } catch (Exception e) {
            throw new RemoteAccessException("访问外部系统异常 " + url);
        }
        return result;
    }

}
